home *** CD-ROM | disk | FTP | other *** search
- -- Interpolation of integer functions by polynomials
- -- with integer coefficients.
-
- -- coeffs of polynomial of degree n agreeing with f at 0,1,..n
- coeffs :: Int -> (Int -> Int) -> [Int]
- coeffs n f = [ coeff_to n k f | k <- [0..n] ]
-
- -- for example Go> coeffs 6 (\x->(x^2-1)^3)
-
- -- Convolve with stirling numbers to get k-th coefficient of function f,
- -- assuming a polynomial of degree n.
- coeff_to :: Int -> Int -> (Int -> Int) -> Int
- coeff_to n k f = alt_sum [s*b | (s,b) <- zip ss bs]
- where ss = [ stir1 (k+i) k | i <- [0..n-k] ]
- bs = drop k (take (n+1) (diffs f))
- alt_sum [] = 0
- alt_sum (x:xs) = x - alt_sum xs
-
- -- stir1 Stirling numbers of the 1-st kind
- stir1 :: Int -> Int -> Int
- stir1 n k | k < 0 = 0
- | n < k = 0
- | n == k = 1
- | otherwise = (n-1)*(stir1 (n-1) k) + stir1 (n-1) (k-1)
-
- -- Get the Newton series of iterated differences of a function f
- diffs :: (Int -> Int) -> [Int]
- diffs f = [ (u 0)/v | (u,v,_) <- iterate step (f,1,1) ]
- where step (h,d,n) = (delta h,n*d,n+1)
- delta h x = (h (x+1)) - (h x)
- iterate g y = y:iterate g (g y)
-
- zip :: [a] -> [b] -> [(a,b)]
- zip as [] = []
- zip [] bs = []
- zip (a:as) (b:bs) = (a,b):zip as bs
-
- drop :: Int -> [a] -> [a]
- drop 0 xs = xs
- drop _ [] = []
- drop (n+1) (x:xs) = drop n xs
-